<template>
  <div class="boxs">
    <el-card shadow="always" :body-style="{ padding: '20px' }">
      <template #header>
        <!-- 自己封装的工具栏组件 -->
        <!-- <ElTools> -->
        <!-- <el-tools> -->
        <PageTools>
          <template #left>
            <span>总记录数：{{ total }}条-混入变量{{ xiaotian }}</span>
          </template>
          <template #right>
            <el-button
              v-if="checkPoints('p-em-import')"
              type="warning"
              @click="$router.push('/import')"
            >
              导入excle
            </el-button>
            <el-button
              :loading="downloadLoading"
              type="danger"
              @click="exportData"
              >导出excle</el-button
            >
            <el-button
              v-if="checkPoints('p-em-add')"
              type="primary"
              @click="show = true"
              >新增员工</el-button
            >
          </template>
        </PageTools>
        <!-- </el-tools> -->
        <!-- </ElTools> -->
      </template>
      <!-- card body -->
      <!-- table列表 -->
      <!-- table列表 -->
      <!--
        1. 通过 Table 的default-sort属性设置默认的排序列和排序顺序
          说明：{prop: '指定按某一列进行排序', order: 'descending'}
        2. 排序方式：ascending 升序（从小到大）   descending 降序（从大到小）

        3.  el-table-column组件身上添加 sortable属性 开启了自排序（手动）
        说明：:sortable="true" = sortable

        关于数据排序：
        1. 前端排序=》假排序（拿到部分数据进行排序）
        2. 后端排序 =》真排序（使用全部数据排序）
        -->
      <el-table
        border
        :data="list"
        :default-sort="{ prop: 'timeOfEntry', order: 'ascending' }"
      >
        <el-table-column type="index" label="序号" />
        <el-table-column prop="username" label="姓名" />
        <!-- 展示员工的头像 -->
        <el-table-column prop="staffPhoto" label="头像">
          <template #default="{ row }">
            <el-image
              @click="openDraw(row.staffPhoto)"
              class="myPhoto"
              :src="row.staffPhoto"
              fit="fill"
            ></el-image>
          </template>
        </el-table-column>
        <el-table-column :sortable="true" prop="workNumber" label="工号" />
        <el-table-column label="聘用形式">
          <template #default="{ row }">
            {{ formatEmploy(row.formOfEmployment) }}
          </template>
        </el-table-column>
        <el-table-column prop="departmentName" label="部门" />
        <el-table-column sortable label="入职时间">
          <template #default="{ row }">
            {{ formatTime(row.timeOfEntry) }}
          </template>
        </el-table-column>
        <el-table-column label="账户状态">
          <template #default="{ row }">
            <el-switch v-model="row.mg"> </el-switch>
          </template>
        </el-table-column>
        <el-table-column label="操作" fixed="right" width="280">
          <template #default="{ row }">
            <el-button
              @click="$router.push(`/employees/detail/${row.id}`)"
              type="text"
              size="small"
              >查看</el-button
            >
            <el-button type="text" @click="openAssign(row.id)" size="small"
              >分配角色</el-button
            >
            <el-button type="text" size="small" @click="delEmployee(row.id)">
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页组件 -->
      <el-row type="flex" justify="center" align="middle" style="height: 60px">
        <el-pagination
          background
          :total="total"
          :current-page="query.page"
          :page-size="query.size"
          :page-sizes="[10, 2]"
          layout="prev, pager, next, sizes"
          @current-change="changePage"
          @size-change="sizeChange"
        />
      </el-row>
    </el-card>

    <!-- 新增员工弹层 -->
    <AddEmploy :show="show" @close="show = false" />
    <!-- 员工头像二维码弹层 -->
    <el-dialog width="250px" title="头像二维码" :visible.sync="showPhoto">
      <canvas ref="cv" />
    </el-dialog>

    <!-- 给员工分配角色弹层 -->
    <AssignRole ref="roles" :show-role-dialog.sync="showRoleDialog" />
  </div>
</template>

<script>
// import ElTools from '@/components/PageTools'
import { getEmployeeListApi, delEmployeeApi } from "@/api/employees";
// 1. 导入数据字典
import Types from "@/api/constant/employees";
// 导入dayjs
import dayjs from "dayjs";
// 导入新增员工的弹层
import AddEmploy from "./components/add-employee.vue";
// 导入二维数据方法
import { transformTdata } from "@/utils";
// 导入给员工分配角色组件
import AssignRole from "./components/assign-role";
// 导入二维码方法
import QrCode from "qrcode";
export default {
  components: {
    // 局部注册
    // ElTools
    AddEmploy,
    AssignRole,
  },
  data() {
    return {
      showRoleDialog: false,
      // 控制头像二维码显隐
      showPhoto: false,
      // 导出loading效果
      downloadLoading: false,
      // 控制新增员工弹层显隐
      show: false,
      // 2. 存储数据字典
      Types,
      // 员工列表数据
      list: [],
      query: {
        page: 1, // 当前页
        size: 10, // 每页条数
      },
      total: 0, // 总数
    };
  },
  mounted() {
    console.log("员工组件实例：", this);
    this.getEmployeeList();
    // 调用全局混入组件方法
    this.checkPoints("我是全局混入方法");
  },
  methods: {
    // 打开员工分配角色弹层
    /**
     * id 员工id
     */
    openAssign(id) {
      // 打开弹层
      this.showRoleDialog = true;
      // 调用分配角色子组件方法做数据回填
      // this.$refs.roles === 分配角色实例
      this.$refs.roles.getRolesById(id);
    },
    // 打开头像二维码弹层并绘制二维码
    openDraw(photoUrl) {
      /**
       * 打开弹层
       * 绘制二维码
       *  dom为一个canvas的dom对象， info为转化二维码的信息 
          语法： QrCode.toCanvas(dom, info)
       */
      (this.showPhoto = true),
        /**
         * 现象：vue修改数据后，dom渲染更新是异步的->提升页面性能
         * 问题：不能获取到异步更新的更新dom
         * 解决：this.$nextTick(callback)
         */
        this.$nextTick(() => {
          QrCode.toCanvas(this.$refs.cv, photoUrl);
          // QrCode.toCanvas(this.$refs.cv, 'http://qq.com')
        });
    },
    // 导出员工信息->下载到本地电脑
    exportData() {
      // 导出下载前开启loading->避免重复点击
      this.downloadLoading = true;
      import("@/utils/Export2Excel").then((excel) => {
        // 核心：准备excel表头和数据
        /**
         * 员工管理页面导出的数据：当前在el-table中显示的员工数据->this.list
         */
        // 1.准备导出数据的map对象：包含要导出员工信息的表头 (中文属性名) 和员工信息的表头 (英文属性名)
        const maps = {
          手机号: "mobile",
          姓名: "username",
          入职日期: "timeOfEntry",
          聘用形式: "formOfEmployment",
          工号: "workNumber",
          转正日期: "correctionTime",
          部门: "departmentName",
        };
        // 2.根据maps对象获取导出员工信息表头(中文属性名)
        const tHeader = Object.keys(maps); // ["手机号", "姓名", "入职日期..."];
        // 3.根据maps对象获取导出员工的数据->把this.list 转换成二维数组(包含员工信息)
        const data = transformTdata(this.list, Object.values(maps));
        // 假数据：
        // const tHeader = ["姓名", "性别", "期望薪资"];
        // // 二维数据
        // const data = [
        //   ["小田", "女", 18000],
        //   ["小殷", "男", 15000],
        //   ["小艳", "女", 18000],
        // ];
        excel.export_json_to_excel({
          header: tHeader, // excel文件表头
          data, // 导出excel数据
          filename: `员工信息-${Math.random()}`, // 下载保存到本地电脑excel文件名
          autoWidth: true, // 单元格自适应
          bookType: "xlsx", // 导出文件格式
        });
        // 下载完关闭loading
        this.downloadLoading = false;
      });
    },
    // 删除员工
    delEmployee(id) {
      this.$confirm("你确认要删除么?", "提示")
        .then(async () => {
          await delEmployeeApi(id);
          // 解决删除最后一页数据页码正确，数据显示错误问题
          const newPage = Math.ceil((this.total - 1) / this.query.size); // 总页数
          if (this.query.page > newPage) {
            // 不正确修复，重新赋值
            this.query.page = newPage;
          }
          this.getEmployeeList();
          this.$message.success("删除员工成功");
        })
        .catch((error) => {
          console.log(error);
        });
    },
    // 格式化员工的入职时间
    formatTime(timeOfEntry) {
      return dayjs(timeOfEntry).format("YYYY年MM月DD日");
    },
    // 格式化聘用形式
    /**
     * type 1 代表正式员工  2 代表非正式员工
     */
    formatEmploy(type) {
      // console.log('数据字典：', this.Types.hireType, type)
      /**
       * 需求：怎么根据type从数据字典[
            {
              id: 1,
              value: '正式'
            },
            {
              id: 2,
              value: '非正式'
            }
          ]
          获取对应ID的value值

          算法思路：
          1. 根据数据字典生成map=》映射关系
          2. 根据map结合type获取value值
       */
      // map = {1:'正式',2:'非正式'}
      const map = {};
      this.Types.hireType.forEach((item) => {
        // 1. 数据ID作为属性名 2. 数据的value作为值
        map[item.id] = item.value;
      });
      // console.log('映射关系：', map, type)

      return map[type];
    },
    // 页码切换
    changePage(newPage) {
      this.query.page = newPage;
      this.getEmployeeList();
    },
    // 每页显示条数切换
    sizeChange(size) {
      this.query.size = size;
      this.getEmployeeList();
    },
    // 获取员工列表
    async getEmployeeList() {
      const data = await getEmployeeListApi(this.query);
      const { total, rows } = data;
      this.total = total;
      this.list = rows;
    },
    importExcel() {
      this.$yuntian();
    },
  },
};
</script>

<style lang="scss" scoped>
.myPhoto {
  width: 80px;
  height: 80px;
  border-radius: 100%;
}
</style>